﻿﻿﻿﻿﻿using DeviceCommons.DataHandling;
using DeviceCommons.DeviceMessages.Enums;
using System.Text;

namespace DeviceCommons.DeviceMessages.Models.V1
{
    public class DeviceMessageInfoReadingState : IDeviceMessageInfoReadingState
    {
        public byte SID { get; set; }
        public byte Type
        {
            get => (byte)ValueType;
            set
            {
                // 验证枚举值的有效性，避免无效值导致的异常
                if (!Enum.IsDefined(typeof(StateValueTypeEnum), value))
                {
                    throw new ArgumentOutOfRangeException(nameof(value), value, 
                        $"Invalid StateValueTypeEnum value: {value}. Valid values are: {string.Join(", ", Enum.GetValues<StateValueTypeEnum>().Cast<byte>())}");
                }
                
                ValueType = (StateValueTypeEnum)value;
                if (ValueType != StateValueTypeEnum.String &&
                    ValueType != StateValueTypeEnum.Binary)
                {
                    Value = new byte[DeviceMessageUtilities.GetValueLength(ValueType, null)];
                }
                else
                {
                    Value = [];
                }
            }
        }

        public byte ValueLength => (StateValueTypeEnum)Type switch { StateValueTypeEnum.String => 1, StateValueTypeEnum.Binary => 2, _ => 0 };

        public byte[] Value { get; set; } = [];

        public object? ValueText
        {
            get
            {
                return (StateValueTypeEnum)Type switch
                {
                    StateValueTypeEnum.Float32 => BitConverter.ToSingle(Value, 0),
                    StateValueTypeEnum.Int32 => BitConverter.ToInt32(Value, 0),
                    StateValueTypeEnum.Bool => BitConverter.ToBoolean(Value, 0),
                    StateValueTypeEnum.UInt16 => BitConverter.ToUInt16(Value, 0),
                    StateValueTypeEnum.Int16 => BitConverter.ToInt16(Value, 0),
                    StateValueTypeEnum.Timestamp => BitConverter.ToUInt64(Value, 0),
                    StateValueTypeEnum.Double => BitConverter.ToDouble(Value, 0),
                    StateValueTypeEnum.Binary => Value, // 返回原始byte[]而不是转换为字符串
                    StateValueTypeEnum.String => Encoding.UTF8.GetString(Value),
                    _ => null,
                };
            }
            set
            {
                Value = (StateValueTypeEnum)Type switch
                {
                    StateValueTypeEnum.Float32 => BitConverter.GetBytes(float.Parse(value?.ToString() ?? "0")),
                    StateValueTypeEnum.Int32 => BitConverter.GetBytes(int.Parse(value?.ToString() ?? "0")),
                    StateValueTypeEnum.Bool => BitConverter.GetBytes(bool.Parse(value?.ToString() ?? "0")),
                    StateValueTypeEnum.UInt16 => BitConverter.GetBytes(ushort.Parse(value?.ToString() ?? "0")),
                    StateValueTypeEnum.Int16 => BitConverter.GetBytes(short.Parse(value?.ToString() ?? "0")),
                    StateValueTypeEnum.Timestamp => BitConverter.GetBytes(ulong.Parse(value?.ToString() ?? "0")),
                    StateValueTypeEnum.Double => BitConverter.GetBytes(double.Parse(value?.ToString() ?? "0")),
                    StateValueTypeEnum.Binary => value is byte[] bytes ? bytes : Encoding.UTF8.GetBytes(value?.ToString() ?? ""),
                    StateValueTypeEnum.String => Encoding.UTF8.GetBytes(value?.ToString() ?? ""),
                    _ => [],
                };
            }
        }
        public StateValueTypeEnum ValueType { get; set; } = StateValueTypeEnum.String;



        public string? Metadata { get; set; }

        public int DataLength => 2 + ValueLength + Value.Length;

        public void Dispose()
        {
            if (Value != null && Value.Length > 0)
            {
                // 只清理数组内容，不返回到内存池
                // 因为Value数组通常不是从内存池租借的（通过new byte[]、BitConverter.GetBytes等创建）
                Array.Clear(Value, 0, Value.Length);
                Value = [];
            }
            GC.SuppressFinalize(this);
        }
    }
}
